﻿using GbopSdk;
using log4net;
using Lotus.AspNetCore.Client.Option;
using Lotus.Domain.Input;
using Lotus.Domain.Input.Lotus;
using Lotus.Domain.Output;
using Lotus.Domain.OutPut.Lotus;
using Newtonsoft.Json;
using RS.BaseModel.Common;
using RS.Tool.Base;
using System.Net;
using System.Text;

namespace Lotus.AspNetCore
{
    public class BaseLotusClient : IBaseLotusClient
    {
        private string _rsaPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuD/eQtZ2SUpGUz4MGFUBWXn+2IAUsutdQ6Se4/bQpxZJCjMsbYxU22086V+4fEfl1SV3z3AW4a23OTuaMxkJlH6sISqQD/2YfT+RJZAa7CupaB2IWWhTNesWe4tk+Q2BFxCufGPM26aXyRggf5J4HUOlqGSEosDkiEstAAlOH4FfIYJaTQgZ7x3gntVydk8XRM7mjkRuhU64NS75QpmarK+mWgTrFdOul08asPueKq6vLyyXuPP1UMQkL36hGPu0Gof8u7kzBQlJsu0aZmGv/IOr4uofadZN58bTWTdo3aNS7c5pp6QF4yhJaxOqmmgHvWHY5zc5wGdTqCyO8yHeQQIDAQAB";

        private string GetLotusUserInfoListApi = "https://passport-test.lotuscars.com.cn/mgt/openapi/v2/mainDataEmp";

        private string GetLotusOrgInfoListApi = "https://passport-test.lotuscars.com.cn/mgt/openapi/v2/mainDataOrg";

        private string StartLotusWorkflowApi = "https://bpm-api-dev.lotuscars.com.cn/workflowEngine/startProcessWithApplicant";

        private string GetStartLotusWorkflowUrlApi = "https://bpm-api-dev.lotuscars.com.cn/workflowEngine/getCompleteInfoUrl";

        private string RecallLotusWorkflowApi = "https://bpm-api-dev.lotuscars.com.cn/workflowEngine/recallProcessWithApplicant";

        private string SendLotusMessageApi = "https://test-gateway-share.lotuscars.com.cn/api/message/msg/sendMsg";

        private string SyncTaskStatusApi = "https://open-test.lotuscars.com.cn/lsrp/gateway/lsrpService/openApi/v1/syncEdis/syncTaskStatusFromEdis";

        private string SyncFdjInfoApi = "https://qmp-test.lotuscars.com.cn/gateway/scaService/openapi/v2/fdj/syncFdjInfo";

        private string GetApplyUrlApi = "https://bpm-api-dev.lotuscars.com.cn/workflowEngine/getApplyUrl";

        private string ReceiveEsowAgreeDocApi = "https://dps-dev.lotuscars.com.cn/cloud-srm/api-brg/bar-anon/external/receiveEsowAgreeDoc";

        private string SaveOrUpdateEsowApi = "http://dps-dev.lotuscars.com.cn/cloud-srm/api-brg/bar-anon/external/esow/saveOrUpdateEsow";

        private static ILog logger = log4net.LogManager.GetLogger("BaseLotusClient");

        private string _Authorization = "";
        private BaseLutosOption _option;
        public BaseLotusClient(BaseLutosOption baseLutosOption)
        {

            _option = baseLutosOption;
        }
        public T ApiGet<T>(string url, string paraStr, Dictionary<string, string?>? header = null)
        {

            if (!string.IsNullOrEmpty(paraStr))
            {

                url = url + "?" + paraStr;
            }

            var resultStr = HttpHelper.Get(url, header);

            if (string.IsNullOrEmpty(resultStr))
            {
                throw new Exception("接口请求结果为空");
            }
            else
            {
                var result = JsonConvert.DeserializeObject<T>(resultStr);
                return result;
            }
        }

        public T ApiGet<T>(string url, object paraObject, Dictionary<string, string?>? header = null)
        {

            var paraStr = "";
            if (paraObject != null)
            {

                var t = paraObject.GetType();

                var pros = t.GetProperties();

                foreach (var o in pros)
                {

                    var name = o.Name;

                    var value = "";

                    var valueObj = o.GetValue(paraObject);

                    if (valueObj != null)
                    {
                        value = valueObj.ToString();
                    }

                    paraStr += $"{name}={value}&";

                }

                if (!string.IsNullOrEmpty(paraStr))
                {

                    paraStr = paraStr.Substring(0, paraStr.Length - 1);

                    paraStr = $"?{paraStr}";
                }
            }
            return this.ApiGet<T>(url, paraStr, header);
        }

        public T ApiPost<T>(string url, object paraObject, Dictionary<string, string?>? header = null)
        {

            var strContent = JsonConvert.SerializeObject(paraObject);

            var resultStr = HttpHelper.Post(url, strContent, header);

            if (string.IsNullOrEmpty(resultStr))
            {
                throw new Exception("接口请求结果为空");
            }
            else
            {
                var result = JsonConvert.DeserializeObject<T>(resultStr);

                return result;
            }

        }

        public Dictionary<string, string?> GetAuthorization()
        {

            var r = new Dictionary<string, string?>()
            {
            };

            if (string.IsNullOrEmpty(_Authorization))
            {
                var authStr = JsonConvert.SerializeObject(new
                {
                    appId = this._option.AppId,
                    appSecret = this._option.AppSecret
                });
                _Authorization = SecretHelper.RSAEncrypt(authStr, _rsaPublicKey, "", false);
            }
            r.Add("Authorization", _Authorization);

            return r;
        }

        public Dictionary<string, string?> GetXLotusAuthorization()
        {

            var r = new Dictionary<string, string?>()
            {
            };

            if (string.IsNullOrEmpty(_Authorization))
            {
                var authStr = JsonConvert.SerializeObject(new
                {
                    appId = this._option.AppId,
                    appSecret = this._option.AppSecret
                });
                _Authorization = SecretHelper.RSAEncrypt(authStr, _rsaPublicKey, "", false);
            }
            r.Add("X-Lotus-Authorization", _Authorization);

            return r;
        }

        public Dictionary<string, string?> GetAppAuthorization()
        {
            var r = new Dictionary<string, string?>()
            {
            };

            if (string.IsNullOrEmpty(_Authorization))
            {
                var authStr = JsonConvert.SerializeObject(new
                {
                    appId = this._option.AppId,
                    appSecret = this._option.AppSecret
                });
                _Authorization = SecretHelper.RSAEncrypt(authStr, _rsaPublicKey, "", false);
            }
            r.Add("AppAuthorization", _Authorization);

            return r;
        }

        public Dictionary<string, string?> GetDPSAuthorization()
        {
            var r = new Dictionary<string, string?>()
            {
            };

            string timestamp = RS.Tool.Base.DateHelper.ToUnixTimestampBySeconds(DateTime.UtcNow.AddHours(8)).ToString();
            r.Add("appId", this._option.DPSId);
            r.Add("timestamp", timestamp);

            string sign = $"{this._option.DPSId}{timestamp}";
            var md51 = RS.Tool.Base.SecretHelper.GetMD5(sign).ToLower();
            var md52 = RS.Tool.Base.SecretHelper.GetMD5($"{this._option.DPSSecret}{md51}").ToLower();
            r.Add("sign", md52);

            return r;
        }
        #region api

        #region 员工中心

        /// <summary>
        /// 获取路特斯员工信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<GetLotusUserInfoListOutput> GetLotusUserInfoList(GetLotusUserInfoListInput input)
        {

            var result = new CommonResult<GetLotusUserInfoListOutput>();

            string url = GetLotusUserInfoListApi;
            if (!string.IsNullOrEmpty(_option.UserDomain))
            {
                url = $"{_option.UserDomain}/mgt/openapi/v2/mainDataEmp";
            }

            var info = this.ApiPost<GetLotusUserInfoListOutput>(url, input, this.GetAuthorization());

            result.IsError = false;

            result.Result = info;

            return result;

        }

        public CommonResult<GetLotusOrgInfoListOutput> GetLotusOrgInfoList(GetLotusOrgInfoListInput input)
        {


            var result = new CommonResult<GetLotusOrgInfoListOutput>();

            string url = GetLotusOrgInfoListApi;
            if (!string.IsNullOrEmpty(_option.UserDomain))
            {
                url = $"{_option.UserDomain}/mgt/openapi/v2/mainDataOrg";
            }

            var info = this.ApiPost<GetLotusOrgInfoListOutput>(url, input, this.GetAuthorization());

            result.IsError = false;

            result.Result = info;

            return result;
        }

        #endregion

        #region BPM

        /// <summary>
        /// 项目过程文件_发起
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<StartLotusWorkflowOutput> StartLotusWorkflow(StartLotusWorkflowInput input)
        {
            var result = new CommonResult<StartLotusWorkflowOutput>();

            string url = StartLotusWorkflowApi;
            if (!string.IsNullOrEmpty(_option.BPMDomain))
            {
                url = $"{_option.BPMDomain}/workflowEngine/startProcessWithApplicant";
            }

            var info = this.ApiPost<StartLotusWorkflowOutput>(url, input, this.GetAppAuthorization());

            result.IsError = false;

            result.Result = info;

            return result;
        }

        /// <summary>
        /// 获取项目过程文件_发起url
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<GetStartLotusWorkflowUrlOutput> GetStartLotusWorkflowUrl(GetStartLotusWorkflowUrlInput input)
        {
            var result = new CommonResult<GetStartLotusWorkflowUrlOutput>();

            string url = GetStartLotusWorkflowUrlApi;
            if (!string.IsNullOrEmpty(_option.BPMDomain))
            {
                url = $"{_option.BPMDomain}/workflowEngine/getCompleteInfoUrl";
            }

            var info = this.ApiGet<GetStartLotusWorkflowUrlOutput>(url, $"instanceId={input.InstanceId}", this.GetAppAuthorization());

            result.IsError = false;

            result.Result = info;

            return result;
        }

        /// <summary>
        /// 项目过程文件_发起撤回输入对象
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<RecallLotusWorkflowOutput> RecallLotusWorkflow(RecallLotusWorkflowInput input)
        {
            var result = new CommonResult<RecallLotusWorkflowOutput>();

            string url = RecallLotusWorkflowApi;
            if (!string.IsNullOrEmpty(_option.BPMDomain))
            {
                url = $"{_option.BPMDomain}/workflowEngine/recallProcessWithApplicant";
            }

            url = $"{url}?instanceId={input.InstanceId}&applicant={input.Applicant}";

            var info = this.ApiPost<RecallLotusWorkflowOutput>(url, input, this.GetAppAuthorization());

            result.IsError = false;

            result.Result = info;

            return result;
        }

        /// <summary>
        /// 获取BPM详情页地址
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<GetApplyLotusWorkflowUrlOutput> GetApplyLotusWorkflowUrl(GetApplyLotusWorkflowUrlInput input)
        {
            var result = new CommonResult<GetApplyLotusWorkflowUrlOutput>();

            string url = GetApplyUrlApi;
            if (!string.IsNullOrEmpty(_option.BPMDomain))
            {
                url = $"{_option.BPMDomain}/workflowEngine/getApplyUrl";
            }

            var info = this.ApiGet<GetApplyLotusWorkflowUrlOutput>(url, $"instanceId={input.InstanceId}&employeeNo={input.EmployeeNo}&defKey={input.DefKey}", this.GetAppAuthorization());

            result.IsError = false;

            result.Result = info;

            return result;
        }

        #endregion

        #region 消息中心

        /// <summary>
        /// 发送路特斯消息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<SendLotusMessageOutput> SendLotusMessage(SendLotusMessageInput input)
        {
            var result = new CommonResult<SendLotusMessageOutput>();

            string url = SendLotusMessageApi;
            if (!string.IsNullOrEmpty(_option.MessageDomain))
            {
                url = $"{_option.MessageDomain}/api/message/msg/sendMsg";
            }
            //没有传参则使用option的参数
            if (string.IsNullOrEmpty(input.TenantId))
            {
                input.TenantId = _option.TenantId;
            }

            StringBuilder paraStrBuilder = new StringBuilder();
            paraStrBuilder.AppendFormat("{0}={1}&", "delaySeconds", input.DelaySeconds);
            paraStrBuilder.AppendFormat("{0}={1}&", "msgBody", input.MsgBody);
            paraStrBuilder.AppendFormat("{0}={1}&", "notifyChannelEnum", input.NotifyChannelEnum);
            paraStrBuilder.AppendFormat("{0}={1}&", "tenantBizId", input.TenantBizId);
            paraStrBuilder.AppendFormat("{0}={1}", "tenantId", input.TenantId);

            paraStrBuilder.Append(_option.TenantSecret);

            if (string.IsNullOrEmpty(input.Sign))
            {
                input.Sign = RS.Tool.Base.SecretHelper.GetMD5(paraStrBuilder.ToString()).ToLower();
            }

            var strContent = JsonConvert.SerializeObject(input);

            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
            httpWebRequest.Method = "POST";
            httpWebRequest.ContentType = "application/json";
            httpWebRequest.Timeout = Timeout.Infinite;
            httpWebRequest.ReadWriteTimeout = Timeout.Infinite;
            httpWebRequest.KeepAlive = false;

            if (!string.IsNullOrWhiteSpace(strContent))
            {
                using StreamWriter streamWriter = new StreamWriter(httpWebRequest.GetRequestStream());
                streamWriter.Write(strContent);
                streamWriter.Close();
            }

            HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            string text = httpWebResponse.ContentEncoding;
            if (text.Length < 1)
            {
                text = "UTF-8";
            }

            StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.GetEncoding(text));
            var resultStr = streamReader.ReadToEnd();

            if (string.IsNullOrEmpty(resultStr))
            {
                throw new Exception("接口请求结果为空");
            }
            else
            {
                var result0 = JsonConvert.DeserializeObject<SendLotusMessageOutput>(resultStr);

                result.IsError = false;

                result.Result = result0;

                return result;
            }
        }

        #endregion

        #region LSRP

        /// <summary>
        /// 标准编制任务完成状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<SyncLSRPTaskStatusOutput> SyncLSRPTaskStatus(SyncLSRPTaskStatusInput input)
        {
            var result = new CommonResult<SyncLSRPTaskStatusOutput>();

            string url = SyncTaskStatusApi;
            if (!string.IsNullOrEmpty(_option.LSRPDomain))
            {
                url = $"{_option.LSRPDomain}/lsrp/gateway/lsrpService/openApi/v1/syncEdis/syncTaskStatusFromEdis";
            }

            var info = this.ApiPost<SyncLSRPTaskStatusOutput>(url, input, this.GetXLotusAuthorization());

            result.IsError = false;

            result.Result = info;

            return result;
        }

        #endregion

        #region QMP

        /// <summary>
        /// 同步Fdj信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<SyncFdjInfoOutput> SyncFdjInfo(List<SyncFdjInfoInput> input)
        {
            var result = new CommonResult<SyncFdjInfoOutput>();

            string url = SyncFdjInfoApi;
            if (!string.IsNullOrEmpty(_option.QMPDomain))
            {
                url = $"{_option.QMPDomain}/gateway/scaService/openapi/v2/fdj/syncFdjInfo";
            }

            var info = this.ApiPost<SyncFdjInfoOutput>(url, input);

            result.IsError = false;

            result.Result = info;

            return result;
        }

        #endregion

        #region DPS
        /// <summary>
        /// 推送签字盖章页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<DPSPushOutput> ReceiveEsowAgreeDoc(DPSPushInput input)
        {
            var result = new CommonResult<DPSPushOutput>();

            string url = ReceiveEsowAgreeDocApi;
            if (!string.IsNullOrEmpty(_option.DPSDomain))
            {
                url = $"{_option.DPSDomain}/cloud-srm/api-brg/bar-anon/external/receiveEsowAgreeDoc";
            }

            var info = this.ApiPost<DPSPushOutput>(url, input, this.GetDPSAuthorization());

            result.IsError = false;

            result.Result = info;

            return result;
        }

        /// <summary>
        /// 推送ESOW
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<SaveOrUpdateEsowOutput> SaveOrUpdateEsow(List<SaveOrUpdateEsowInput> input)
        {
            var result = new CommonResult<SaveOrUpdateEsowOutput>();

            string url = SaveOrUpdateEsowApi;
            if (!string.IsNullOrEmpty(_option.DPSDomain))
            {
                url = $"{_option.DPSDomain}/cloud-srm/api-brg/bar-anon/external/esow/saveOrUpdateEsow";
            }

            var info = this.ApiPost<SaveOrUpdateEsowOutput>(url, input, this.GetDPSAuthorization());

            result.IsError = false;

            result.Result = info;

            return result;
        }

        #endregion

        #region EPS
        /// <summary>
        /// 推送签字盖章页
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<EPSPushOutput> ReceiveEsowAgreeDocForEPS(EPSPushInput input)
        {
            var result = new CommonResult<EPSPushOutput>();
            if (input == null)
                return result;
            GbopRequest requestItem = new GbopRequest();
            requestItem.AK = this._option.EPSId;
            requestItem.SK = this._option.EPSSecret;
            requestItem.Method = GbopHttpMethod.POST;
            requestItem.HostUrl = this._option.EPSDomain;
            requestItem.PATH = "/exchange/esow/signature/save";
            requestItem.ContentJson = JsonConvert.SerializeObject(input);            
            try
            {
                GbopResponse gresult = GbopHelper.ExeHttp(requestItem);
                if (gresult != null && !string.IsNullOrEmpty(gresult.ResponseResult))
                {
                    logger.Info("推送EPS签字盖章 返回:" + gresult.ResponseResult);
                    result.Result = JsonConvert.DeserializeObject<EPSPushOutput>(gresult.ResponseResult);
                }
                result.IsError = false;
            }
            catch (Exception ex)
            {
            }
            return result;
        }

        /// <summary>
        /// 推送ESOW
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public CommonResult<SaveOrUpdateEsowForEPSOutput> SaveOrUpdateEsowForEPS(List<SaveOrUpdateEsowForEPSInput> input)
        {
            var result = new CommonResult<SaveOrUpdateEsowForEPSOutput>();
            if (input == null || input.Count == 0)
                return result;
            GbopRequest requestItem = new GbopRequest();
            requestItem.AK = this._option.EPSId;
            requestItem.SK = this._option.EPSSecret;
            requestItem.Method = GbopHttpMethod.POST;
            requestItem.HostUrl = this._option.EPSDomain;
            requestItem.PATH = "/exchange/esow/save";
            requestItem.ContentJson = JsonConvert.SerializeObject(input);            
            try
            {
                GbopResponse gresult = GbopHelper.ExeHttp(requestItem);
                if (gresult != null && !string.IsNullOrEmpty(gresult.ResponseResult))
                {
                    logger.Info("推送EPS 返回:" + gresult.ResponseResult);
                    result.Result = JsonConvert.DeserializeObject<SaveOrUpdateEsowForEPSOutput>(gresult.ResponseResult);
                }
                result.IsError = false;
            }
            catch (Exception ex)
            {
            }
            return result;
        }

        #endregion
        #endregion

    }
}
